package com.chat.api.web.service;


import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.chat.api.common.exception.ApiException;
import com.chat.api.utils.util.ParamUtil;
import com.chat.api.web.dao.UserRepo;
import com.chat.api.web.po.UserBean;
import com.chat.api.utils.ResultUtil;
import com.chat.api.utils.util.IdWorkerUtil;
import com.chat.api.utils.util.SmsUtils;
import com.chat.api.web.vo.MessageEntity;
import com.chat.api.web.vo.SmsEnum;
import com.chat.api.web.vo.UserEntity;
import com.google.common.collect.Lists;
import io.netty.util.internal.StringUtil;
import org.apache.commons.lang3.RandomStringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.servlet.ModelAndView;
import redis.clients.jedis.Jedis;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.Base64;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;

@Service
@Transactional(readOnly = true)
public class UserService {

    @Autowired
    private UserRepo userRepo;
    @Resource
    private RedisTemplate<String,Object> redisTemplate;
    @Autowired
    private ChatService chatService;

    /**
     * 用户注册
     * @param entity
     * @return
     */
    @Transactional(readOnly = false)
    public MessageEntity registerAccount(UserEntity entity) {
        try {
            //校验用户名能否使用
            if (entity.getUsername() == null || entity.getUsername().trim().isEmpty()){
                return ResultUtil.fail("用户名不能为空");
            }else if (entity.getUsername().length()<5 || entity.getUsername().length()>15){
                return ResultUtil.fail("用户名的长度只能在5-15之间");
            }else if (userRepo.queryByUsername(entity.getUsername()) != null){
                return ResultUtil.fail("用户名已存在，请更换用户名");
            }else if (userRepo.queryByName(entity.getName()) != null){
                return ResultUtil.fail("昵称已存在，请更换昵称");
            }else if (!checkname(entity.getName()) || entity.getName().length()<1 || entity.getName().length()>5){
                return ResultUtil.fail("昵称必须为汉字，长度只能在1-5之间");
            }
            //校验密码
            if (entity.getPassword() == null || entity.getPassword().trim().isEmpty()){
                return ResultUtil.fail("密码不能为空");
            }else if (entity.getPassword().length()<5 || entity.getPassword().length()>15){
                return ResultUtil.fail("密码的长度只能在5-15之间");
            }
//            //校验确认密码是否和密码一致
//            if (entity.getConfirmPassword() == null || entity.getConfirmPassword().trim().isEmpty()){
//                return ResultUtil.fail("确认密码不能为空");
//            }else if (!entity.getConfirmPassword().equals(entity.getPassword())){
//                return ResultUtil.fail("两次密码不一致");
//            }
//            校验验证码：和redis中的验证码进行对比
            if (!entity.getVscode().equals("54188")){
                String verifyCode = (String) redisTemplate.opsForValue().get(entity.getPhone());
                if (verifyCode.isEmpty()){
                    return ResultUtil.fail("验证码已失效，请重新发送");
                }else if (!entity.getVscode().equals(verifyCode)){
                    return ResultUtil.fail("验证码有误，请重新输入");
                }
            }
            //走到这里表名以上参数全部有效，可以进行账号注册
            UserBean userBean = new UserBean();
            entity.setBean(userBean);
            userBean.setId(IdWorkerUtil.getInstance().nextId());
            userBean.setCreateDate(new Date());
            //密码用base64加密
            byte[] bytes = userBean.getPassword().getBytes();
            byte[] encode = Base64.getEncoder().encode(bytes);
            userBean.setPassword(new String(encode));
            userRepo.save(userBean);
            return ResultUtil.success("注册成功！");
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.fail("系统繁忙，请稍后注册！");
        }

    }

    /**
     * 登录
     * @return
     */
    public MessageEntity login(String username, String password, HttpServletRequest req, HttpServletResponse response, String position) {
        try {
//            UserBean bean = userRepo.queryByUsername(entity.getUsername());
//            if (bean == null){
//                return ResultUtil.fail("账号或密码不正确！");
//            }
            UserBean bean = userRepo.queryByUsername(username);
            byte[] bytes = password.getBytes();
            byte[] encode = Base64.getEncoder().encode(bytes);
            String passwordBase = new String(encode);
            if (bean == null){
                return ResultUtil.fail("该账号不存在！");
            }
            if (!bean.getPassword().equals(passwordBase)){
                return ResultUtil.fail("账号或密码不正确！");
            }
            //获取Session对象
            HttpSession session = req.getSession();
            //将用户保存到session域中
            session.setAttribute(session.getId(),bean.getId().toString());
            redisTemplate.opsForValue().set(session.getId(),bean.getId().toString());
            redisTemplate.expire(session.getId(),30,TimeUnit.MINUTES);
            String s = position.replaceAll("市", "");
            redisTemplate.opsForValue().set("session"+session.getId(),s);
            redisTemplate.expire("session"+session.getId(),30,TimeUnit.MINUTES);
            return ResultUtil.success(bean);
        }catch (Exception e){
            e.printStackTrace();
            return ResultUtil.fail("系统繁忙，请稍后重试！");
        }

    }

    /**
     * 发送验证码
     * @param entity
     * @return
     */
    public MessageEntity sendCode(String phone) {
        try {
            //手机号验证
            String cellphone = (String) redisTemplate.opsForValue().get(phone+"time");
            Integer time = 1;
            if (cellphone != null){
                time = Integer.valueOf(cellphone);
            }
            if (time > 3){
                return ResultUtil.fail("您今天发送短信次数过多，请24小时后再试!!!");
            }else {
                time++;
                redisTemplate.opsForValue().set(phone+"time",time.toString());
                redisTemplate.expire(phone+"time",1,TimeUnit.DAYS);
            }
            String code = RandomStringUtils.randomNumeric(6);
            SendSmsResponse sendSmsResponse = SmsUtils.sendSms(phone, code, SmsEnum.sendCode.smsCode);
            System.out.println("*********************发送验证码: " + phone);
            String result = sendSmsResponse.getCode();
            if (!result.equals("OK")){
                return ResultUtil.fail("站主太穷，短信发送业务里的余额不足，无法发送短信了T-T。。。,验证码直接输入54188,奥利给！！！");
            }
            //TODO 将验证码存入redis
            redisTemplate.opsForValue().set(phone,code);
            redisTemplate.expire(phone,300, TimeUnit.SECONDS);
            if (result.equals("OK")){
                System.out.println("*********************发送验证码成功！！！：" + phone);
//                redisTemplate.opsForValue().set(phone+"time",time.toString());
//                redisTemplate.expire(phone+"time",1,TimeUnit.DAYS);
                return ResultUtil.success("短信发送成功！！！");
            }else {
                return ResultUtil.fail("短信发送失败！！！");
            }
        }catch (Exception c){
            c.printStackTrace();
            return ResultUtil.fail("系统繁忙，请稍后再试！");
        }

    }

    /**
     * 皇家社区密码验证
     * @param entity
     * @return
     */
    public Boolean verify(UserEntity entity) {
        try {
            String password = entity.getPassword();
            if (StringUtil.isNullOrEmpty(password)) return  false;
            if (password.equals("1234")){
                return true;
            }
            return false;
        }catch (Exception e){
            e.printStackTrace();
            throw new ApiException("密码验证失败");
        }
    }

    public Boolean adytum(UserEntity entity) {
        try {

            return true;
        }catch (Exception e){
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 用户登出
     * @param req
     * @return
     */
    public MessageEntity logOut(HttpServletRequest req, HttpServletResponse response) throws IOException {
        HttpSession session = req.getSession();
        Object user = session.getAttribute(session.getId());
        if (user != null){
            session.removeAttribute(session.getId());
        }
        req.getSession().setMaxInactiveInterval(0);
        req.getSession().removeAttribute(req.getSession().getId());
        redisTemplate.delete(session.getId());
        redisTemplate.delete("session"+session.getId());
        return ResultUtil.success("/templates/login.html");
    }

    /**
     * 密码找回
     * @param entity
     * @return
     */
    public MessageEntity findPwd(UserEntity entity) {
        try {
            Jedis jedis = new Jedis();
            String verifyCode = jedis.get("cellphone");
            if (verifyCode.isEmpty()){
                return ResultUtil.fail("验证码已失效，请重新发送");
            }else if(!entity.getVscode().equals(verifyCode)){
                return ResultUtil.fail("验证码有误，请重新输入");
            }
            if (entity.getVscode().equals(verifyCode)){
                UserBean bean = userRepo.queryByUsername(entity.getUsername());
                SendSmsResponse sendSmsResponse = SmsUtils.sendSms(bean.getPhone(), bean.getPassword(), SmsEnum.findPwd.getSmsCode());
                String code = sendSmsResponse.getCode();
                if (code.equals("OK")){
                    return ResultUtil.success("已将密码以短信形式发送给您，请注意查看！");
                }
            }
            return ResultUtil.fail("系统繁忙，请稍后再试！！！");
        }catch (Exception e){
            e.printStackTrace();
            throw new ApiException("密码找回异常！！！");
        }
    }

    public UserBean findById(Long id) {
        return userRepo.getOne(id);
    }

    /**
     * 获取主页面所需数据
     * @return
     */
    public List<UserBean> getAll() {
        try {
            List<UserBean> all = userRepo.findAllMain();
            return all;
        }catch (Exception e){
            e.printStackTrace();
            throw new ApiException("主页面数据获取失败！！！");
        }
    }

    /**
     * 获取用户列表
     * @param req
     * @return
     */
    public List<UserEntity> findUser(HttpServletRequest req) {
        try {
            HttpSession session = req.getSession();
            String userIdS = (String) session.getAttribute(session.getId());
            Long userId = ParamUtil.getLongParameter(userIdS, -1L);
            List<UserBean> all = userRepo.findAllNotSelf(userId);
            List<UserEntity> entities = Lists.newArrayList();
            for (UserBean userBean : all) {
                UserEntity entity = new UserEntity();
                Integer count = 0;
                entity.setEntity(userBean);
                try {
                    count = chatService.findNoReadCount(userBean.getId(),userId);
                    entity.setNoRead(String.valueOf(count));
                }catch (Exception e){
                    entity.setNoRead(String.valueOf(count));
                }
                entities.add(entity);
            }
            return entities;
        }catch (Exception e){
            e.printStackTrace();
            throw new ApiException("获取用户列表失败！！！");
        }
    }

    public String getNameById(Long userId) {
        try {
            UserBean userBean = userRepo.findByUserId(userId);
            return userBean.getName();
        }catch (Exception e){
            e.printStackTrace();
            throw new ApiException("获取用户名称失败！！！");
        }
    }

    public UserBean findByUserInfo(HttpServletRequest req) {
        try {
            HttpSession session = req.getSession();
            String userId = (String) session.getAttribute(session.getId());
            UserBean bean = userRepo.findByUserId(Long.parseLong(userId));
            UserEntity userEntity = new UserEntity();
            userEntity.setEntity(bean);
            return bean;
        }catch (Exception e){
            e.printStackTrace();
            throw new ApiException("获取用户信息失败！！!");
        }
    }

    //判断是否是中文
    public static boolean checkname(String name) {
        int n = 0;
        for(int i = 0; i < name.length(); i++) {
            n = (int)name.charAt(i);
            if(!(19968 <= n && n <40869)) {
                return false;
            }
        }
        return true;
    }

    public UserBean findByName(String name) {
        return userRepo.findByName(name);
    }
}
